/***************************************************************************
 *            main.c
 *
 *  Sun Oct 30 18:00:29 2005
 *  Copyright  2005  Yitzhak Grossman
 *  celejar@gmail.com
 ****************************************************************************/

/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 

/* main routines for sudoku generator */


#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define WII
#ifndef WII
#include <time.h>
#include "../include/sudoku.h"
#else
#define random() rand()
#include "sudoku.h"
#endif

/* function prototypes */

void fill(struct sudoku_info *sudoku);
void thin(struct sudoku_info *sudoku);
void init(struct sudoku_info *sudoku);

/* Global (s) */

int Solutions;

#ifndef WII
int main()
{
	struct sudoku_info sudoku;
	init(&sudoku);
	fill(&sudoku);
	//~ display_grid(&sudoku);
	thin(&sudoku);
	display_grid(&sudoku);
	return 0;
}
void init(struct sudoku_info *sudoku)
{
	#if defined DEBUG1
		unsigned int seed;
 	#endif
	#if defined DEBUG2
		unsigned int seed;
	#endif
	sud_struct_zero(sudoku);
	srandom((unsigned int)time(NULL));
	#if defined DEBUG2
		printf("Enter seed: ");
		scanf("%u", &seed);
		srandom(seed);
	#endif
	#if defined DEBUG1
		seed = time(NULL);
		printf("# Seed is %u\n", seed);
		srandom((unsigned int)seed);
	#endif
}
#endif

void fill(struct sudoku_info *sudoku)
{
	int i, j, value;
	static struct sudoku_info new_sudoku;
	/* display_grid(sudoku); */
for(;;)
{
	do
	{
		Solutions = 0;
		memcpy(&new_sudoku, sudoku, sizeof(struct sudoku_info));
		while(sudoku->grid[i = random() % 9][j = random() % 9]);
		while(sudoku->info[i][j][value = random() % 9] != MAYBE);
		set_cell(&new_sudoku, i, j, value + 1);
		/* if (Solutions == 1) return 1; */
		solve(&new_sudoku);
		if (Solutions == 1) 
		{
			set_cell(sudoku, i, j, value + 1);
			return;
		}
	} while (!Solutions);
	set_cell(sudoku, i, j, value + 1);
	/* memcpy(sudoku, &new_sudoku, sizeof(struct sudoku_info)); */
}
//	fill(sudoku);
	return;
}
void thin(struct sudoku_info *sudoku)
{
	int grid[9][9], i, j, k, l, left = sudoku->known;
	struct sudoku_info new_sudoku1, new_sudoku2;
	for (i = 0; i < 9; i++)
		for (j = 0; j < 9; j++)
			grid[i][j] = sudoku->grid[i][j];
	while (left)
	{
		l = random() % left;
		k = -1;
		for (i = 0; i < 9; i++)
		{
			for (j = 0; j < 9; j++)
			{
				if (!grid[i][j]) continue;
				if (++k == l) break;
			}
			if (k == l) break;
		}
		//~ printf("Trying %d at %d,%d...\n", grid[i][j], i, j);
		grid[i][j] = 0;
		/* printf("%d\n", left--); */
		left--;
		sud_struct_zero(&new_sudoku1);
		for (k = 0; k < 9; k++)
			for (l = 0; l < 9; l++)
				if (sudoku->grid[k][l] && !(k == i && l == j))
					set_cell(&new_sudoku1, k, l, sudoku->grid[k][l]);
		Solutions = 0;
		memcpy(&new_sudoku2, &new_sudoku1, sizeof(struct sudoku_info));
		//~ display_grid(&new_sudoku2);
		solve(&new_sudoku2);
		if (Solutions == 2) continue;
		if (Solutions == 0) {printf("Error!\n"); exit(1);}
		//~ printf("Eliminating.\n");
		memcpy(sudoku, &new_sudoku1, sizeof(struct sudoku_info));
	}
}
void sud_struct_zero(struct sudoku_info *sudoku)
{
	int i, j, k;
	sudoku->known = 0;
	for (i = 0; i < 9; i++)
		for (j = 0; j < 9; j++)
		{
			sudoku->grid[i][j] = 0;
			for (k = 0; k < 9; k++) sudoku->info[i][j][k] = MAYBE;
		}
}
